package me.softwareengineer.guice.rendering.domain;

import java.util.List;
import java.util.Map;

import me.softwareengineer.guice.rendering.listener.EndMacroMetadataEvent;
import me.softwareengineer.guice.rendering.listener.Listener;
import me.softwareengineer.guice.rendering.listener.StartMacroMetadataEvent;
import me.softwareengineer.guice.rendering.util.CollectionUtil;

/**
 * A special block that Macro Blocks generate when they are executed so that
 * it's possible to reconstruct the initial syntax even after Macros have been
 * executed. For example this is important in a WYSWIYG editor where you want to
 * show the Macro's rendered result and also let users modify the macro content.
 * 
 * @author yad.tahir
 * 
 */
public class MacroMetaDataElement extends Element {
	/**
	 * Holds the id of macro. For instance, php for php macro
	 */
	private final String id;
	
	/**
	 * The macro content that we are preserving.
	 */
	private final String content;
	
	/**
	 * The macro is located in a inline content (like paragraph, etc.).
	 */
	private final boolean isInline;
	
	/**
	 * Creates a macro metadata element
	 * 
	 * @param id
	 *            the id of the macro. See {@link #getId()}
	 * @param isInline
	 *            If true the macro is located in a inline content (like
	 *            paragraph, etc.).
	 * @param properties
	 *            the properties of the element. See {@link HasProperties}
	 * @param children
	 *            the children of the element
	 */
	public MacroMetaDataElement(String id, boolean isInline,
			Map<String, String> properties, List<Element> children) {
		super(children);
		this.setProperties(properties);
		this.id = id;
		this.content = null;
		this.isInline = isInline;

	}

	/**
	 * Creates a macro metadata element
	 * 
	 * @param id
	 *            the id of the macro. See {@link #getId()}
	 * @param isInline
	 *            If true the macro is located in a inline content (like
	 *            paragraph, etc.).
	 * @param properties
	 *            the properties of the element. See {@link HasProperties}
	 * @param children
	 *            the children of the element
	 * @param content
	 *            the script/content of macro
	 */
	public MacroMetaDataElement(String id, boolean isInline,
			Map<String, String> properties, List<Element> children,
			String content) {
		super(children);
		this.setProperties(properties);
		this.id = id;
		this.isInline = isInline;
		this.content = content;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void afterElement(Listener listener) {
		EndMacroMetadataEvent e = new EndMacroMetadataEvent(getId(),
				isInline(), getContent(), getAllProperties(), getAllMetaData());
		listener.onEvent(e);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void beforeElement(Listener listener) {
		StartMacroMetadataEvent e = new StartMacroMetadataEvent(getId(),
				isInline(), getContent(), getAllProperties(), getAllMetaData());
		listener.onEvent(e);
	}

	/**
	 * 
	 * @return the content or the script of the macro
	 * <p>
	 * This property is immutable and thread-safe
	 * </p>
	 */
	public String getContent() {
		
			return content;
		

	}

	/**
	 * 
	 * @return the id of macro. For instance, php for php macro
	 * <p>
	 * This property is immutable and thread-safe
	 * </p>
	 */
	public String getId() {
	
			return id;
		

	}

	/**
	 * 
	 * @return if true the macro is located in a inline content (like paragraph,
	 *         etc.).
	 * <p>
	 * This property is immutable and thread-safe
	 * </p>
	 */
	public boolean isInline() {
			return isInline;
	}

	
}
